#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
 
#include "data_type.h"
#include "alloc.h"
#include "memfunc.h"
#include "basefunc.h"
#include "struct_deal.h"
#include "crypto_func.h"
#include "memdb.h"
#include "message.h"
#include "ex_module.h"
#include "sys_func.h"

#include "virtual_node.h"
// add para lib_include
int virtual_node_init(void * sub_proc, void * para)
{
	int ret;
    char uuid_str[DIGEST_SIZE*2+1];
	BYTE uuid[DIGEST_SIZE];
	char proc_name[DIGEST_SIZE];

    // Init virtuan node Func
    struct virtual_node_para * virt_para=para;
    if((virt_para==NULL) || (virt_para->virt_type==0))
    // normal node
    {
        return 0;
    }
    else if(virt_para->virt_type == 1)
    // virtual node, need to change node_uuid to a virtual uuid
    {
        // build virtual_node struct and change uuid
        RECORD(MESSAGE,VIRTUAL_NODE) * virtual_node;
        virtual_node =Talloc0(sizeof(*virtual_node));
        if(virtual_node ==NULL)
            return -ENOMEM;
        Strncpy(virtual_node->domain,virt_para->domain,DIGEST_SIZE);


		if(virt_para->node_name != NULL)
		{
			Strncpy(virtual_node->node_name,virt_para->node_name,DIGEST_SIZE);
			calculate_context_sm3(virtual_node->node_name,Strlen(virtual_node->node_name),virtual_node->node_uuid);
			proc_share_data_setvalue("uuid",virtual_node->node_uuid);
			Memset(uuid_str,0,DIGEST_SIZE*2+1);
			digest_to_uuid(virtual_node->node_uuid,uuid_str);
        
			print_cubeaudit("virtual_node init :change virtual node uuid to %s name to %s!",uuid_str,virtual_node->node_name);
			proc_share_data_getvalue("proc_name",proc_name);
			comp_proc_uuid(virtual_node->node_uuid,proc_name,uuid);
			digest_to_uuid(uuid,uuid_str);
			print_cubeaudit("virtual_node init : change instance's local proc uuid to %s\n",uuid_str);
		}
		
        // store virtual_node struct
        DB_RECORD * db_record;
        db_record = memdb_find_byname("default",TYPE_PAIR(MESSAGE,VIRTUAL_NODE));
        if(db_record != NULL)
        {
            print_cubeaudit("change virtual node node_name to %s!",virtual_node->node_name);
            memdb_remove(db_record->head.uuid,TYPE_PAIR(MESSAGE,VIRTUAL_NODE));
        }
        memdb_store(virtual_node,TYPE_PAIR(MESSAGE,VIRTUAL_NODE),"default");
    }
	return 0;
}
int virtual_node_start(void * sub_proc, void * para)
{
	int ret;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here

		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			return ret;
		if(recv_msg==NULL)
			return 0;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			ex_module_sendmsg(sub_proc,recv_msg);
		}
		else
		{
			ret=proc_attach_virtnodeinfo(sub_proc,recv_msg);
		}


	return 0;
}

int proc_attach_virtnodeinfo(void * sub_proc,void * recv_msg)
{
	int ret=0;
	int fd;

	RECORD(MESSAGE,VIRTUAL_NODE)  virtual_node;

	printf("begin virtual node info  attach!\n");
    DB_RECORD * db_record;

    db_record = memdb_find_byname("default",TYPE_PAIR(MESSAGE,VIRTUAL_NODE));
    if(db_record != NULL)
    {
         ret=message_add_expand_data(recv_msg,TYPE_PAIR(MESSAGE,VIRTUAL_NODE),db_record->record);   
    }

	ret=ex_module_sendmsg(sub_proc,recv_msg);

	return ret;
}

